package parser

import (
    "caculator-script/lexer"
    "caculator-script/lexer/token"
    "caculator-script/parser/ast"
    "github.com/gogf/gf/errors/gerror"
    "github.com/gogf/gf/util/gconv"
)

type Parser interface {
    // Parse 传入脚本,解析为语法树
    Parse(string) (ast.Node, error)
    
    // DumpTree 将语法树输出为人可以看的模式
    DumpTree(ast.Node)
}

func NewDefaultParser() Parser {
    return NewParser(lexer.NewDefaultLexer())
}

func NewParser(l lexer.Lexer) Parser {
    return &parser{
        lexer: l,
    }
}

type parser struct {
    lexer lexer.Lexer
}

func (p *parser) Parse(s string) (ast.Node, error) {
    reader := p.lexer.Tokenize(s)
    return p.parse(reader)
}

func (p *parser) DumpTree(node ast.Node) {
}

func (p *parser) parse(reader token.TokenReader) (ast.Node, error) {
    // 建立程序根节点
    rootNode := ast.NewRootSimpleNode()
    
    for reader.Peek() != nil {
        token := reader.Peek()
        
        child := p.intDeclaration(reader)
        
        if child == nil {
            child = p.expressionStmt(reader)
        }
        
        if child == nil {
            child = p.assignmentStmt(reader)
        }
        
        if child != nil {
            rootNode.AddChildren(child)
        } else {
            return nil, gerror.New("不符合我们语法规则" + token.Value() + ":" + gconv.String(token.Line()))
        }
    }
    
    return rootNode, nil
}

func (p *parser) intDeclaration(reader token.TokenReader) ast.Node {
    return nil
}

func (p *parser) expressionStmt(reader token.TokenReader) ast.Node {
    return nil
}

func (p *parser) assignmentStmt(reader token.TokenReader) ast.Node {
    return nil
}
